package board.grid;

import java.util.Collection;
/** A basic container used to hold the objects
 *  associate them with a location, such that
 *  they can be displayed in a <code>GridPane</code>.  This
 *  system allows for any range of grid-based
 *  games and systems to be produced.
 *  
 *  When an instance of this interface is modified,
 *  such as when an occupant is moved/added/removed, 
 *  it is necessary to call repaint of the
 *  <code>GridPane</code> that is displaying that grid to
 *  ensure that the GridPane shows that latest
 *  version of the grid.  The Grid, by default,
 *  will not update the display.  
 * 
 * @author R.Wisniewski1101
 *
 * @param <T> - the type of occupants in this Grid
 */
public interface Grid<T> {
	/** Get all of the occupants of this <code>Grid</code>
	 * 
	 * @return - the occupants of this Gird.  
	 */
	public Collection<T>		getAll();
	/** Get the space that contains the specified
	 *  occupant.  
	 * 
	 * @param occupant - the occupant for which to find the space which contains it
	 * @return - the containing space, null if not on grid
	 */
	public Space				getCurrentSpace(Object occupant);
	/** Get the width of the grid.  This may
	 *  not necessarily be the actual width
	 *  of the grid that has occupants, just
	 *  the width of the area that is intended
	 *  to be displayed by the <code>GridPane</code>.  
	 * 
	 * @return - the preferred width of the area to display.  
	 */
	public int					getWidth();
	/** Get the height of the grid.  This may
	 *  not necessarily be the actual height
	 *  of the grid that has occupants, just
	 *  the height of the area that is intended
	 *  to be displayed by the <code>GridPane</code>.  
	 * 
	 * @return - the preferred height of the area to display.  
	 */
	public int					getHeight();
	/** Get the row number of the first row to display.  
	 * 
	 * @return - the row number
	 */
	public int					getMinRow();
	/** Get the column number of the first column to display
	 * 
	 * @return - the column number
	 */
	public int					getMinCol();
	/** Get the all of the spaces that currently
	 *  have occupants.  
	 * 
	 * @return - the occupied spaces
	 */
	public Collection<Space>	getOccupiedSpaces();
	/** Place a new occupant in a given space.  
	 * 
	 * @throws IllegalArgumentException - the grid will does not contain the given space or the newOccupant is null
	 * @param space - the space to place the occupant
	 * @param newOccupent - the object to place
	 * @return - the old occupant of that location, null is previously un-occupied. 
	 */
	public T					put(Space space, T newOccupent);
	/** Remove the occupant from that space.  
	 * 
	 * @param space - the space of which to remove the occupant
	 * @return - the occupant removed
	 */
	public T					remove(Space space);
	/** Get the occupant of that space.  
	 * 
	 * @param space - the space of which to get the occupant
	 * @return - the occupant
	 */
	public T					get(Space space);
	/** Is a space valid on this grid?  
	 * 
	 * @param space - the space to check
	 * @return - validity
	 */
	public boolean				isValidSpace(Space space);
	/** Get all of the valid spaced within
	 *  one space of the given space.  
	 * 
	 * @param space - the center space
	 * @return - the valid spaces
	 */
	public Collection<Space>	getValidSurroundingSpaces(Space space);
	/** Get all of the spaces around a given
	 *  space that are valid on this grid, and
	 *  are within a given distance from the
	 *  given space.  
	 * 
	 * @param space - the space at the center of the search area (not included in the return)
	 * @param radius - the distance to search
	 * @return - the valid spaces
	 */
	public Collection<Space>	getValidSurroundingSpaces(Space space, int radius);
	/** Get all of the spaces around a given
	 *  space that are within one space away
	 *  and are not occupied.  
	 * 
	 * @param space - the center space
	 * @return - the empty spaces
	 */
	public Collection<Space>	getEmptySurroundingSpaces(Space space);
	/** Get all of the spaces around a given
	 *  space that are within a given distance
	 *  and are not occupied.  
	 * 
	 * @param space - the center space
	 * @param radius - the distance to search
	 * @return - the empty spaces
	 */
	public Collection<Space>	getEmptySurroundingSpaces(Space space, int radius);
	/** Get all of the spaces around a given
	 *  space that are within one space away
	 *  and are occupied.  
	 * 
	 * @param space - the center space
	 * @return - the occupied spaces
	 */
	public Collection<Space>	getOccupiedSurroundingSpaces(Space space);
	/** Get all of the spaces around a given
	 *  space that are within a given distance
	 *  and are occupied.  
	 * 
	 * @param space - the center space
	 * @param radius - the distance to search
	 * @return - the occupied spaces
	 */
	public Collection<Space>	getOccupiedSurroundingSpaces(Space space, int radius);
	/** Get all of the occupants that are within
	 *  one space from the given space (exclusive).  
	 * 
	 * @param space - the center space
	 * @return - the surrounding occupants
	 */
	public Collection<T>		getSurroundingOccupents(Space space);
	/** Get all of the occupants that are within
	 *  a given distance from the given space
	 *  (exclusive).  
	 * 
	 * @param space - the center space
	 * @param radius - the distance to search
	 * @return - the surrounding occupants
	 */
	public Collection<T>		getSurroundingOccupents(Space space, int radius);
	/** Get an Iterable of all of the occupants
	 *  of this grid.  This is used primarily
	 *  with <code>for-each</code> loops.  
	 * 
	 * @return - an Iterable of the occupants
	 */
	public Iterable<T>			allOccupants();
	/** Get an Iterable of all of the occupied
	 *  spaces on this grid.  This is used primarily
	 *  with <code>for-each</code> loops. 
	 * 
	 * @return - an Iterable of the occupied spaces
	 */
	public Iterable<Space>		allOccupiedSpaces();
	/** Get an Iterable of all of the valid
	 *  spaces of the grid.  This is used primarily
	 *  with <code>for-each</code> loops. 
	 * 
	 * @return - an Iterable of all valid spaces
	 */
	public Iterable<Space>		allValidSpaces();
}
